package com.jsy.common.util;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.PdfSection;
import com.spire.pdf.exporting.PdfImageInfo;
import com.spire.pdf.graphics.PdfImage;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;

public class PdfUtil {


    public static void main(String[] args) throws IOException {
        //使用pdfbox会出现空白页面
//        pdf2png("H:/book/","《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局","jpg");
//        pdf2png("F:\\book\\shu","EVIDENCE IN TRIALS AT COMMON LAW","jpg");
        // 使用spire.pdf pdf转图片处理空白页面问题（如果pdf中有空白页，会阻塞，需删除空白页）
//        pdf2image();
        //支持批量去除图片水印
//        ImageWaterConverter.convertAllImages("H:/book/out", "H:/book/water");
        //将图片截成两半
//        ImageHelper.cutHalfImageFromDir();
        //使用spire.pdf 将单个图片转PDF，然后合并所有pdf，占用内存太大限制800个文件
//        batchImageToPDF();
//        mergepdf();
        //使用lowagie.text
        image2pdf();
    }

    private static void mergepdf() {
        int i = mergeDocuments("H:/book/merge", 0);
        while (i!= -1){
            i = mergeDocuments("H:/book/merge", i);
        }
    }

    private static void batchImageToPDF() {
        File file = new File("H:/book/water/cut");
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            try {
                convertImageToPDF(file.getPath(),files[i].getName(),"H:/book/merge");
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
    }

    public static void image2pdf() {
        long time1 = System.currentTimeMillis();
        toPdf("F:\\book\\done\\", "F:\\book\\done2.pdf");
        long time2 = System.currentTimeMillis();
        int time = (int) ((time2 - time1)/1000);
        System.out.println("执行了："+time+"秒！");
    }

    public static void pdf2image() throws IOException {
        //加载PDF文件
        PdfDocument doc = new PdfDocument();
        doc.loadFromFile("H:/book/《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局.pdf");
        System.out.println(doc.getPages().getCount());
        String filedir="H:/book/out";
        File file1 = new File(filedir);
        if (!file1.exists()){
            file1.mkdir();
        }
        //保存PDF的每一页到图片
        BufferedImage image;
        for (int i = 0; i < doc.getPages().getCount(); i++) {
            image = doc.saveAsImage(i);
//            File file = new File( String.format("ToImage-img-%d.png", i));
            File file = new File( "H:/book/out/"+String.format("%d.png", i));
            ImageIO.write(image, "PNG", file);
            System.out.println("========="+file.getAbsolutePath()+"=======");
        }

        doc.close();
    }

    /**
     * 删除pdf中的图片，可指定页码
     */
    public static void deleteImageFirstApproach() {
        //Pdf file
        String file = "H:/book/《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局.pdf";

        //Open pdf document
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile(file);

        //Get the first page
        PdfPageBase page = pdf.getPages().get(0);

        PdfImageInfo[] imageInfo = page.getImagesInfo();

        //Delete the first image on the page
        page.deleteImage(imageInfo[0].getImage().getMinTileX());

        String result = "H:/book/《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局.pdf";

        //Save the document
        pdf.saveToFile(result, FileFormat.PDF);
    }

    /**
     * 删除pdf指定的页码
     */
    public static void deletePage() {
        String inputFile ="H:/book/《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局.pdf";
        String outputFile = "H:/book/《JINPINGMEI词话》梦梅馆校定本 梅节校注 陈少卿抄阅 里仁书局.pdf";

        //Load PDF document
        PdfDocument doc = new PdfDocument(inputFile);

        //Delete the third page
        doc.getPages().removeAt(0);

        //Save the document
        doc.saveToFile(outputFile);
        doc.close();
    }
    public static void convertImageToPDF(String dir1,String filename,String dir2){
        // Create a pdf document with a section and page added.
        PdfDocument pdf = new PdfDocument();
        PdfSection section = pdf.getSections().add();
        PdfPageBase page = pdf.getPages().add();

        //Load a tiff image from system
        PdfImage image = PdfImage.fromFile(dir1+"/"+filename);

        //Set image display location and size in PDF
        //Calculate rate
        double widthFitRate = image.getPhysicalDimension().getWidth() / page.getCanvas().getClientSize().getWidth();
        double heightFitRate = image.getPhysicalDimension().getHeight() / page.getCanvas().getClientSize().getHeight();
        double fitRate = Math.max(widthFitRate, heightFitRate);

        //Calculate the size of image
        double fitWidth = image.getPhysicalDimension().getWidth() / fitRate;
        double fitHeight = image.getPhysicalDimension().getHeight() / fitRate;

        //Draw image
        page.getCanvas().drawImage(image, 0, 30, fitWidth, fitHeight);

        String output = dir2+"/"+filename.substring(0,filename.lastIndexOf("."))+".pdf";
        pdf.saveToFile(output);
        pdf.close();
    }
    /**
     * 转换全部的pdf
     * @param fileAddress 文件地址
     * @param filename PDF文件名
     * @param type 图片类型
     */
    public static void pdf2png(String fileAddress,String filename,String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress+"\\"+filename+".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//                ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));
                ImageIO.write(image, type, new File(fileAddress+(i+1)+"."+type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     *自由确定起始页和终止页
     * @param fileAddress 文件地址
     * @param filename pdf文件名
     * @param indexOfStart 开始页  开始转换的页码，从0开始
     * @param indexOfEnd 结束页  停止转换的页码，-1为全部
     * @param type 图片类型
     */
    public static void pdf2png(String fileAddress,String filename,int indexOfStart,int indexOfEnd,String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress+"\\"+filename+".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = indexOfStart; i < indexOfEnd; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//                ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));
                ImageIO.write(image, type, new File(fileAddress+(i+1)+"."+type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 合并多个pdf文档
     */
    public static int mergeDocuments(String dir,int start) {
        //Pdf document list
//        String[] files = new String[]
//                {
//                        "H:\\book\\merge\\0.pdf",
//                        "H:\\book\\merge\\0.pdf",
//                        "H:\\book\\merge\\0.pdf"
//                };
        File file = new File(dir);
        if (!file.exists()){
            return 0;
        }
        File[] files = file.listFiles();
        arraySort(files);
        //Open pdf documents
        PdfDocument[] docs = new PdfDocument[files.length];
        PdfDocument doc = new PdfDocument();
        if (start==0){
            docs[0] = new PdfDocument();
            docs[0].loadFromFile(files[0].getAbsolutePath());
        }else {
            docs[0] = new PdfDocument();
            docs[0].loadFromFile("H:\\book\\0.pdf");
        }
        int limit=800;
        if (files.length-start>800){
            for (int i = start+1; i < start+limit; i++) {
                docs[i] = new PdfDocument();
                docs[i].loadFromFile(files[i].getAbsolutePath());
                docs[0].appendPage(docs[i]);
                System.out.println(i);
            }
        }else {
            for (int i = start; i < files.length; i++) {
                docs[i] = new PdfDocument();
                docs[i].loadFromFile(files[i].getAbsolutePath());
                docs[0].appendPage(docs[i]);
                System.out.println(i);
            }
            start=-801;
        }
        //Append document

//        docs[0].appendPage(docs[1]);

//        Import pages
//        for (int i = 0; i < docs[2].getPages().getCount(); i = i + 2) {
//            docs[0].insertPage(docs[2], i);
//        }

        // Save pdf file
        String output = "H:\\book\\0.pdf";
        docs[0].saveToFile(output, FileFormat.PDF);
        doc.close();
        return start+limit;
    }
    /**
     *
     * @param imageFolderPath
     *            图片文件夹地址
     * @param pdfPath
     *            PDF文件保存地址
     *
     */
    public static void toPdf(String imageFolderPath, String pdfPath) {
        try {
            // 图片文件夹地址
            // String imageFolderPath = "D:/Demo/ceshi/";
            // 图片地址
            String imagePath = null;
            // PDF文件保存地址
            // String pdfPath = "D:/Demo/ceshi/hebing.pdf";
            // 输入流
            FileOutputStream fos = new FileOutputStream(pdfPath);
            // 创建文档
            Document doc = new Document(null, 0, 0, 0, 0);
            //doc.open();
            // 写入PDF文档
            PdfWriter.getInstance(doc, fos);
            // 读取图片流
            BufferedImage img = null;
            // 实例化图片
            Image image = null;
            // 获取图片文件夹对象
            File file = new File(imageFolderPath);
            File[] files = file.listFiles();
            //排序
            //如果o1在o2之前，则返回-1，如果相同，则返回0，如果o1在o2之后，则返回1
            arraySort(files);
            // 循环获取图片文件夹内的图片
            int index = 0;
            for (File file1 : files) {
                index ++;
                if (index <= 520){
                    continue;
                }
                if (file1.getName().endsWith(".png")
                        || file1.getName().endsWith(".jpg")
                        || file1.getName().endsWith(".gif")
                        || file1.getName().endsWith(".jpeg")
                        || file1.getName().endsWith(".tif")) {
                    // System.out.println(file1.getName());
                    imagePath = imageFolderPath + file1.getName();
                    System.out.println(file1.getName());
                    // 读取图片流
                    img = ImageIO.read(new File(imagePath));
                    // 根据图片大小设置文档大小
                    doc.setPageSize(new Rectangle(img.getWidth(), img
                            .getHeight()));
                    // 实例化图片
                    image = Image.getInstance(imagePath);
                    // 添加图片到文档
                    doc.open();
                    doc.add(image);
                }
            }
            // 关闭文档
            doc.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BadElementException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    public static void arraySort(File[] files) {
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                int index1 = o1.getName().lastIndexOf(".");
                int index2 = o2.getName().lastIndexOf(".");
                try {
                String substring1 = o1.getName().substring(3, index1);
                String substring2 = o2.getName().substring(3, index2);
                    if (Integer.parseInt(substring1)<Integer.parseInt(substring2)){
                        return -1;
                    }else {
                        return 1;
                    }
                } catch (Exception e) {
                    return 0;
                }
            }
        });
    }
}
